home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-19
/
intrlib1.zip
/
WINDOW.C
< prev
Wrap
C/C++ Source or Header
|
1992-03-05
|
67KB
|
1,799 lines
/******************************************************************************
* Iteraction library - windows. *
* *
* Written by Gershon Elber, Oct. 1990 *
*******************************************************************************
* Special notes: *
* The operations allowed on windows here guarantee that windows defines a *
* total order. I.e. for each two windows (even if not overlap) one can say *
* which one is above which. *
*******************************************************************************
* History: *
* 7 Oct 90 - Version 1.0 by Gershon Elber. *
******************************************************************************/
#include <stdio.h>
#include <string.h>
#ifdef __MSDOS__
#include <mem.h>
#include <dos.h>
#endif /* __MSDOS__ */
#include "intr_loc.h"
#include "intr_gr.h"
#define MIN_WINDOW_SIZE 50 /* 50 by 50 is minimum size allowed. */
#define DEFAULT_FXMIN -1.0
#define DEFAULT_FYMIN -1.0
#define DEFAULT_FXMAX 1.0
#define DEFAULT_FYMAX 1.0
#define MAP_OBJ_TO_WNDW_X(x) ((int) (DrawingWindow -> BBox._Dx * \
(x - DrawingWindow -> FBBox.FXmin) / \
DrawingWindow -> FBBox._FDx))
#define MAP_OBJ_TO_WNDW_Y(y) ((int) (DrawingWindow -> BBox._Dy * \
(y - DrawingWindow -> FBBox.FYmin) / \
DrawingWindow -> FBBox._FDy))
AsyncEventStruct
_IntrAsyncLastEvent =
{ ASYNC_EVNT_NONE, INTR_EVNT_NONE, NULL, 0.0, 0, 0, 0, 0 };
static int
WindowIDCounter = 1; /* Allocate unique window I.D.'s. */
static IntrRType
RealCursorX, RealCursorY; /* Real cursor coords. */
static IntrBType
SelectAllWindows = TRUE; /* Default - all windows are selected. */
static _IntrWindowStruct
*GlblWindowsList = NULL, /* All windows defined. */
*DrawingWindow = NULL, /* Window in which drawing is taking place. */
*SelectedWindow = NULL; /* Selected window (usually where cursor is). */
static IntrBBoxStruct
ResizeBBox = { 0, 0, 1000, 1000, 1000, 1000};
static void MoveWindowToTop(_IntrWindowStruct *Window);
static void RedrawWindow(_IntrWindowStruct *Window);
static void DrawWindowFrameAndName(_IntrWindowStruct *Window);
static void DrawWindowOnePixelFrame(int Xmin, int Ymin, int Xmax, int Ymax,
IntrColorType Color, IntrIntensityType BottomRightColor,
IntrIntensityType TopLeftColor);
static void IntrWndwPutStatus(_IntrWindowStruct *Window, int Color);
static void ClipPositionToResizeBBox(int *x, int *y, int Width, int Height);
static void DeleteWindowFromGlblList(_IntrWindowStruct *Window);
static void InsertWindowFirstGlblList(_IntrWindowStruct *Window);
static void InsertWindowLastGlblList(_IntrWindowStruct *Window);
/******************************************************************************
* Returns TRUE if scroll bar event had occured on the given window. Returns *
* in Value the scroll bar fraction. Should be called only from async. refresh *
* functions called by WindowRefresh below. *
******************************************************************************/
IntrBType IntrWndwIsScrollBarEvent(int WindowID, IntrBType *IsVertical,
IntrRType *Value)
{
if (_IntrAsyncLastEvent.Window != NULL &&
_IntrAsyncLastEvent.Window -> WindowID == WindowID &&
(_IntrAsyncLastEvent.AsyncEvent == ASYNC_EVNT_HSCRLBAR ||
_IntrAsyncLastEvent.AsyncEvent == ASYNC_EVNT_VSCRLBAR)) {
*Value = _IntrAsyncLastEvent.R;
*IsVertical = _IntrAsyncLastEvent.AsyncEvent == ASYNC_EVNT_VSCRLBAR;
_IntrAsyncLastEvent.AsyncEvent = ASYNC_EVNT_NONE;
return TRUE;
}
else
return FALSE;
}
/******************************************************************************
* Returns the width (in pixels) of a scroll bar. *
******************************************************************************/
int IntrWndwScrollBarWidth(void)
{
return _INTR_SCROLL_BAR_WIDTH + 2;
}
/******************************************************************************
* Redraw all active windows. *
******************************************************************************/
void IntrWndwRedrawAll(void)
{
_IntrWindowStruct *Window;
IntrPushCursorType();
GRClearAllScreen();
for (Window = GlblWindowsList;
Window != NULL;
Window = Window -> Pnext)
{
if (Window -> MappedToScreen)
RedrawWindow(Window);
}
IntrPopCursorType();
}
/******************************************************************************
* Clear a window to its background color. *
* Window is selected as new drawing window. *
******************************************************************************/
void IntrWndwClear(int WindowID)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
_GRSetViewPort(0, 0, GRScreenMaxX, GRScreenMaxY);
GRSetWriteMode(GR_COPY_PUT);
GRSetLineStyle(GR_SOLID_LINE, 0, GR_NORM_WIDTH);
IntrAllocColor(Window -> BackColor, INTR_INTENSITY_HIGH);
GRSBar(Window -> BBox.Xmin,
Window -> BBox.Ymin,
Window -> BBox.Xmax,
Window -> BBox.Ymax);
DrawingWindow = Window; /* Select this window as the drawing window. */
GRSetZoomFactor(DrawingWindow -> ZoomFactor);
GRSetPanFactors(DrawingWindow -> PanFactorX, DrawingWindow -> PanFactorY);
GRSetViewPort(DrawingWindow -> BBox.Xmin,
DrawingWindow -> BBox.Ymin,
DrawingWindow -> BBox.Xmax,
DrawingWindow -> BBox.Ymax);
if (!IntrWndwIsAllVisible(WindowID))
MoveWindowToTop(Window);
}
/******************************************************************************
* Move window to top of list and clear it to its background color. *
******************************************************************************/
static void MoveWindowToTop(_IntrWindowStruct *Window)
{
GRPushViewPort();
_GRSetViewPort(0, 0, GRScreenMaxX, GRScreenMaxY);
IntrPushCursorType();
GRSetWriteMode(GR_COPY_PUT);
/* Draw window frame and window name. */
DrawWindowFrameAndName(Window);
/* If it has Pull Down menu - draw it as well. */
if (Window -> PDMenu)
_IntrPullDownMenuDrawItems(Window -> PDMenu);
IntrAllocColor(Window -> BackColor, INTR_INTENSITY_HIGH);
GRSBar(Window -> BBox.Xmin, Window -> BBox.Ymin,
Window -> BBox.Xmax, Window -> BBox.Ymax);
IntrPopCursorType();
GRPopViewPort();
}
/******************************************************************************
* Redraw the given window. Preform the following operations in the following *
* order: *
* 1. Draw the border with the specified color and width. If border width is *
* zero no border is drawn. If Window has WindowName a header with this *
* name is created as part of the border. *
* 2. Clear the window interior to the specified back ground color. *
* 3. Call the refresh function for this window if such function is defined. *
******************************************************************************/
static void RedrawWindow(_IntrWindowStruct *Window)
{
MoveWindowToTop(Window);
/* Apply the redrawing function. */
DrawingWindow = Window; /* Select this window as the drawing window. */
GRSetZoomFactor(DrawingWindow -> ZoomFactor);
GRSetPanFactors(DrawingWindow -> PanFactorX, DrawingWindow -> PanFactorY);
GRSetViewPort(DrawingWindow -> BBox.Xmin,
DrawingWindow -> BBox.Ymin,
DrawingWindow -> BBox.Xmax,
DrawingWindow -> BBox.Ymax);
IntrPushCursorType();
if (Window -> RefreshFunc != NULL)
(Window -> RefreshFunc)(Window -> WindowID);
IntrPopCursorType();
}
/******************************************************************************
* Draw the window frame. If the window has a name header associated with it, *
* it is drawn as well on the top of the window. *
******************************************************************************/
static void DrawWindowFrameAndName(_IntrWindowStruct *Window)
{
int Xmin = Window -> BBox.Xmin,
Ymin = Window -> BBox.Ymin,
Xmax = Window -> BBox.Xmax,
Ymax = Window -> BBox.Ymax,
Width = Window -> FrameWidth;
IntrBType SlctdWndw = Window == SelectedWindow || SelectAllWindows;
IntrPullDownMenuStruct *PDMenu = Window -> PDMenu;
int PDMenuHeight = PDMenu == NULL ? 0 :
IntrWndwGetHeaderHeight("M", PDMenu -> FrameWidth);
GRSetLineStyle(GR_SOLID_LINE, 0, GR_NORM_WIDTH);
/* Draw the window frame. */
_IntrWndwDrawFrame(Xmin, Xmax, Ymin, Ymax, Width,
Window -> FrameColor, FALSE,
Window -> HScrlBarColor, Window -> HScrlBar,
Window -> VScrlBarColor, Window -> VScrlBar,
SlctdWndw);
/* If window has a name associated with it draw the name on top. */
if (Window -> DrawHeader && Window -> Name != NULL) {
_IntrWndwPutNameHeader(Xmin - Window -> FrameWidth -
(Window -> VScrlBar == INTR_SCRLBAR_LEFT
? _INTR_SCROLL_BAR_WIDTH + 1 : 0),
Xmax + Window -> FrameWidth +
(Window -> VScrlBar == INTR_SCRLBAR_RIGHT
? _INTR_SCROLL_BAR_WIDTH + 1 : 0),
Ymin - Window -> FrameWidth - 2 - PDMenuHeight -
(Window -> HScrlBar == INTR_SCRLBAR_TOP
? _INTR_SCROLL_BAR_WIDTH + 1 : 0),
Window -> FrameWidth, Window -> Name, FALSE,
Window -> FrameColor, Window -> FrameColor,
Window -> BackColor, SlctdWndw);
IntrWndwPutStatus(Window,
IntrAllocColor(Window -> FrameColor,
INTR_INTENSITY_VHIGH));
}
}
/******************************************************************************
* Routine to draw a window frame with the sppecified BBox and width. *
* The X/Ymin/max coordinates are of the inner (net) window. *
******************************************************************************/
void _IntrWndwDrawFrame(int Xmin, int Xmax, int Ymin, int Ymax, int Width,
IntrColorType FrameColor, IntrBType SaveUnder,
IntrColorType HScrlBarColor, IntrScrlBarType HScrlBar,
IntrColorType VScrlBarColor, IntrScrlBarType VScrlBar,
IntrBType HighIntensity)
{
int i,
Width4 = Width >> 2;
Xmin -= VScrlBar == INTR_SCRLBAR_LEFT ? _INTR_SCROLL_BAR_WIDTH + 1 : 0;
Xmax += VScrlBar == INTR_SCRLBAR_RIGHT ? _INTR_SCROLL_BAR_WIDTH + 1 : 0;
Ymin -= HScrlBar == INTR_SCRLBAR_TOP ? _INTR_SCROLL_BAR_WIDTH + 1 : 0;
Ymax += HScrlBar == INTR_SCRLBAR_BOTTOM ? _INTR_SCROLL_BAR_WIDTH + 1 : 0;
if (SaveUnder && _IntrSaveBelow)
_IntrSaveWindow(Xmin - Width, Ymin - Width,
Xmax + Width, Ymax + Width);
/* First quarter is drawn in low color intensity. */
for (i = 1; i <= Width4; i++)
DrawWindowOnePixelFrame(Xmin - i, Ymin - i, Xmax + i, Ymax + i,
FrameColor,
INTR_INTENSITY_LOW, INTR_INTENSITY_VLOW);
/* Middle half is drawn in high color intensity. */
for (i = Width4 + 1; i <= Width - Width4; i++)
DrawWindowOnePixelFrame(Xmin - i, Ymin - i, Xmax + i, Ymax + i,
FrameColor,
HighIntensity ? INTR_INTENSITY_VHIGH
: INTR_INTENSITY_HIGH,
HighIntensity ? INTR_INTENSITY_VHIGH
: INTR_INTENSITY_HIGH);
/* Last quarter is drawn in low color intensity. */
for (i = Width - Width4 + 1; i <= Width; i++)
DrawWindowOnePixelFrame(Xmin - i, Ymin - i, Xmax + i, Ymax + i,
FrameColor,
INTR_INTENSITY_VLOW, INTR_INTENSITY_LOW);
switch (VScrlBar) {
case INTR_SCRLBAR_LEFT:
DrawWindowOnePixelFrame(Xmin, Ymin,
Xmin + _INTR_SCROLL_BAR_WIDTH, Ymax,
FrameColor,
HighIntensity ? INTR_INTENSITY_VHIGH
: INTR_INTENSITY_HIGH,
HighIntensity ? INTR_INTENSITY_VHIGH
: INTR_INTENSITY_HIGH);
IntrAllocColor(VScrlBarColor, INTR_INTENSITY_LOW);
GRSBar(Xmin + 1, Ymin + 1,
Xmin + _INTR_SCROLL_BAR_WIDTH - 1, Ymax - 1);
break;
case INTR_SCRLBAR_RIGHT:
DrawWindowOnePixelFrame(Xmax - _INTR_SCROLL_BAR_WIDTH, Ymin,
Xmax, Ymax,
FrameColor,
HighIntensity ? INTR_INTENSITY_VHIGH
: INTR_INTENSITY_HIGH,
HighIntensity ? INTR_INTENSITY_VHIGH
: INTR_INTENSITY_HIGH);
IntrAllocColor(VScrlBarColor, INTR_INTENSITY_LOW);
GRSBar(Xmax - _INTR_SCROLL_BAR_WIDTH + 1, Ymin + 1,
Xmin - 1, Ymax - 1);
break;
}
/* Make Xmin/max back to the real window dimenstion. */
Xmin += VScrlBar == INTR_SCRLBAR_LEFT ? _INTR_SCROLL_BAR_WIDTH + 1 : 0;
Xmax -= VScrlBar == INTR_SCRLBAR_RIGHT ? _INTR_SCROLL_BAR_WIDTH + 1 : 0;
switch (HScrlBar) {
case INTR_SCRLBAR_TOP:
DrawWindowOnePixelFrame(Xmin, Ymin,
Xmax, Ymin + _INTR_SCROLL_BAR_WIDTH,
FrameColor,
HighIntensity ? INTR_INTENSITY_VHIGH
: INTR_INTENSITY_HIGH,
HighIntensity ? INTR_INTENSITY_VHIGH
: INTR_INTENSITY_HIGH);
IntrAllocColor(HScrlBarColor, INTR_INTENSITY_LOW);
GRSBar(Xmin + 1, Ymin + 1,
Xmax - 1, Ymin + _INTR_SCROLL_BAR_WIDTH - 1);
break;
case INTR_SCRLBAR_BOTTOM:
DrawWindowOnePixelFrame(Xmin, Ymax - _INTR_SCROLL_BAR_WIDTH,
Xmax, Ymax,
FrameColor,
HighIntensity ? INTR_INTENSITY_VHIGH
: INTR_INTENSITY_HIGH,
HighIntensity ? INTR_INTENSITY_VHIGH
: INTR_INTENSITY_HIGH);
IntrAllocColor(HScrlBarColor, INTR_INTENSITY_LOW);
GRSBar(Xmin + 1, Ymax - _INTR_SCROLL_BAR_WIDTH + 1,
Xmax - 1, Ymax - 1);
break;
}
}
/****************************************************************************
* Routine to update a scroll bar of a specified window. *
* RelativePosition and DisplayedFraction controls beginning of scroll bar *
* active zone and its length respectively. *
****************************************************************************/
void IntrWndwUpdateScrollBar(int WindowID,
IntrBType IsVertical,
IntrRType RelativePosition,
IntrRType DisplayedFraction)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
int Xmin = Window -> BBox.Xmin,
Ymin = Window -> BBox.Ymin,
Xmax = Window -> BBox.Xmax,
Ymax = Window -> BBox.Ymax;
if (IsVertical) {
switch (Window -> HScrlBar) {
case INTR_SCRLBAR_TOP:
Ymin -= _INTR_SCROLL_BAR_WIDTH + 1;
break;
case INTR_SCRLBAR_BOTTOM:
Ymax += _INTR_SCROLL_BAR_WIDTH + 1;
break;
}
switch (Window -> VScrlBar) {
case INTR_SCRLBAR_LEFT:
_IntrUpdateScrollBar(Xmin - 1 - _INTR_SCROLL_BAR_WIDTH, Ymin,
Xmin - 1, Ymax,
RelativePosition, DisplayedFraction,
TRUE, Window -> VScrlBarColor);
break;
case INTR_SCRLBAR_RIGHT:
_IntrUpdateScrollBar(Xmax + 1, Ymin,
Xmax + 1 + _INTR_SCROLL_BAR_WIDTH, Ymax,
RelativePosition, DisplayedFraction,
TRUE, Window -> VScrlBarColor);
break;
default:
IntrFatalError("Window does not have a scroll bar.");
}
}
else {
switch (Window -> HScrlBar) {
case INTR_SCRLBAR_TOP:
_IntrUpdateScrollBar(Xmin, Ymin - 1 - _INTR_SCROLL_BAR_WIDTH,
Xmax, Ymin - 1,
RelativePosition, DisplayedFraction,
FALSE, Window -> HScrlBarColor);
break;
case INTR_SCRLBAR_BOTTOM:
_IntrUpdateScrollBar(Xmin, Ymax + 1,
Xmax, Ymax + 1 + _INTR_SCROLL_BAR_WIDTH,
RelativePosition, DisplayedFraction,
FALSE, Window -> HScrlBarColor);
break;
default:
IntrFatalError("Window does not have a scroll bar.");
}
}
}
/****************************************************************************
* Routine to draw a scroll bar in the given coordinates, given size of the *
* DisplayedFraction and the current RelativePosition. *
* View port is assumed to be the entire screen. *
****************************************************************************/
void _IntrUpdateScrollBar(int Left,
int Top,
int Right,
int Bottom,
IntrRType RelativePosition,
IntrRType DisplayedFraction,
IntrBType IsVertical,
IntrColorType ScrlBarColor)
{
int ActiveMin, ActiveMax ,
Dx = Right - Left,
Dy = Bottom - Top;
Left++;
Top++;
Right--;
Bottom--;
GRPushViewPort();
_GRSetViewPort(Left, Top, Right, Bottom);
GRSetLineStyle(GR_SOLID_LINE, 0, GR_NORM_WIDTH);
IntrAllocColor(ScrlBarColor, INTR_INTENSITY_LOW);
GRSBar(0, 0, Right - Left, Bottom - Top);
IntrAllocColor(ScrlBarColor, INTR_INTENSITY_VHIGH);
if (IsVertical) {
ActiveMin = ((int) (Dy * RelativePosition));
ActiveMax = ActiveMin + ((int) (Dy * DisplayedFraction));
GRSBar(0, ActiveMin, Dx, MIN(ActiveMax, Dy - 2));
}
else { /* Horizontal. */
ActiveMin = ((int) (Dx * RelativePosition));
ActiveMax = ActiveMin + ((int) (Dx * DisplayedFraction));
GRSBar(ActiveMin, 0, MIN(ActiveMax, Dx - 2), Dy);
}
GRPopViewPort();
}
/******************************************************************************
* Returns the expected height of the header created by _IntrWndwPutNameHeader.*
******************************************************************************/
int IntrWndwGetHeaderHeight(char *Header, int FrameWidth)
{
int Height;
GRPushTextSetting();
GRSetSTextStyle(GR_FONT_DEFAULT, GR_HORIZ_DIR, GR_TEXT_MAG_1);
Height = GRGetTextHeight(Header) + 4 + (FrameWidth << 1);
GRPopTextSetting();
return Height;
}
/******************************************************************************
* Routine to put horizontal bar with given size string and color. *
* Bar height will be string height + 4 + FrameWidth * 2 pixels. *
******************************************************************************/
void _IntrWndwPutNameHeader(int Xmin, int Xmax, int Ymax, int FrameWidth,
char *Str, IntrBType SaveUnder,
IntrColorType FrameColor, IntrColorType ForeColor,
IntrColorType BackColor, IntrBType HighIntensity)
{
char CpStr[80];
int i, Width, Ymin, XStr, YStr, Color,
Width4 = FrameWidth >> 2;
GRPushTextSetting();
GRSetTextJustify(GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_BOTTOM);
GRSetSTextStyle(GR_FONT_DEFAULT, GR_HORIZ_DIR, GR_TEXT_MAG_1);
GRSetLineStyle(GR_SOLID_LINE, 0, GR_NORM_WIDTH);
strncpy(CpStr, Str, 79);
/* Prepare some parameters and make sure string will not overflow. */
while ((Width = GRGetTextWidth(CpStr)) > Xmax - Xmin - (FrameWidth << 1) &&
Width > 0)
CpStr[strlen(CpStr) - 1] = 0;
Ymin = Ymax - IntrWndwGetHeaderHeight(CpStr, FrameWidth);
if (SaveUnder && _IntrSaveBelow)
_IntrSaveWindow(Xmin - FrameWidth, Ymin - FrameWidth,
Xmax + FrameWidth, Ymax + FrameWidth);
XStr = (Xmin + Xmax - Width) >> 1;
YStr = Ymax - FrameWidth - 2;
/* First quarter is always drawn in high/low color intensity. */
for (i = 0; i < Width4; i++)
DrawWindowOnePixelFrame(Xmin + i, Ymin + i, Xmax - i, Ymax - i,
FrameColor,
INTR_INTENSITY_VLOW, INTR_INTENSITY_LOW);
/* Middle half is drawn in very high/high color intensity. */
for (i = Width4; i < FrameWidth - Width4; i++)
DrawWindowOnePixelFrame(Xmin + i, Ymin + i, Xmax - i, Ymax - i,
FrameColor,
HighIntensity ? INTR_INTENSITY_VHIGH
: INTR_INTENSITY_HIGH,
HighIntensity ? INTR_INTENSITY_VHIGH
: INTR_INTENSITY_HIGH);
/* Last quarter is always drawn in high/low color intensity. */
for (i = FrameWidth - Width4; i < FrameWidth; i++)
DrawWindowOnePixelFrame(Xmin + i, Ymin + i, Xmax - i, Ymax - i,
FrameColor,
INTR_INTENSITY_LOW, INTR_INTENSITY_VLOW);
/* Inner header is in back ground color. */
IntrAllocColor(BackColor, INTR_INTENSITY_HIGH);
GRSBar(Xmin + FrameWidth, Ymin + FrameWidth,
Xmax - FrameWidth, Ymax - FrameWidth);
/* And finally draw the window name. */
Color = IntrAllocColor(ForeColor, INTR_INTENSITY_VHIGH);
if (strlen(CpStr) > 0) {
GRSTextShadow(XStr, YStr, Color, CpStr);
}
GRPopTextSetting();
}
/******************************************************************************
* Routine to print status string on left and right of window header. *
* Note it is assumed the window HAS an header active (i.e. its name != NULL). *
******************************************************************************/
static void IntrWndwPutStatus(_IntrWindowStruct *Window, int Color)
{
int Xmin = Window -> BBox.Xmin,
Ymin = Window -> BBox.Ymin,
Xmax = Window -> BBox.Xmax;
GRPushViewPort();
_GRSetViewPort(0, 0, GRScreenMaxX, GRScreenMaxY);
GRPushTextSetting();
GRSetTextJustify(GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_BOTTOM);
GRSetSTextStyle(GR_FONT_DEFAULT, GR_HORIZ_DIR, GR_TEXT_MAG_1);
switch (Window -> VScrlBar) {
case INTR_SCRLBAR_LEFT:
Xmin -= _INTR_SCROLL_BAR_WIDTH;
break;
case INTR_SCRLBAR_RIGHT:
Xmax += _INTR_SCROLL_BAR_WIDTH;
break;
}
switch (Window -> HScrlBar) {
case INTR_SCRLBAR_TOP:
Ymin -= _INTR_SCROLL_BAR_WIDTH;
break;
}
if (Window -> PDMenu != NULL)
Ymin -= IntrWndwGetHeaderHeight("M", Window -> PDMenu -> FrameWidth);
if (Window -> StatusLeft) {
GRSetTextJustify(GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_BOTTOM);
GRSTextShadow(Xmin + 2,
Ymin - (Window -> FrameWidth << 1) - 4,
Color,
Window -> StatusLeft);
}
if (Window -> StatusRight != NULL) {
GRSetTextJustify(GR_TEXT_HJUSTIFY_RIGHT, GR_TEXT_VJUSTIFY_BOTTOM);
GRSTextShadow(Xmax - 2,
Ymin - (Window -> FrameWidth << 1) - 4,
Color,
Window -> StatusRight);
}
GRPopTextSetting();
GRPopViewPort();
}
/******************************************************************************
* Boolean function to determine if two given bbox domains overlap. *
******************************************************************************/
static void DrawWindowOnePixelFrame(int Xmin, int Ymin, int Xmax, int Ymax,
IntrColorType Color, IntrIntensityType BottomRightColor,
IntrIntensityType TopLeftColor)
{
IntrAllocColor(Color, BottomRightColor);
GRSMoveTo(Xmax, Ymin);
GRSLineTo(Xmax, Ymax);
GRSLineTo(Xmin, Ymax);
IntrAllocColor(Color, TopLeftColor);
GRSLineTo(Xmin, Ymin);
GRSLineTo(Xmax, Ymin);
}
/******************************************************************************
* Find window structure using its I.D.. Return NULL if not found. *
******************************************************************************/
_IntrWindowStruct *_IntrFindWndwUsingID(int WindowID)
{
_IntrWindowStruct *Windows;
for (Windows = GlblWindowsList;
Windows != NULL;
Windows = Windows -> Pnext) {
if (Windows -> WindowID == WindowID) return Windows;
}
IntrFatalError("Window ID was not found.");
return NULL;
}
/******************************************************************************
* Function to select all windows. This mode is in fact the default and in *
* this mode ALL window's frames are drawn at maximum *
* intensity. If FALSE only the SelectedWindow frame will be at maximum. *
******************************************************************************/
void IntrWndwSelectAll(IntrBType SelectAll)
{
SelectAllWindows = SelectAll;
}
/******************************************************************************
* Select a window. This has the effect of making its frame intensified. *
******************************************************************************/
void IntrWndwSelect(int WindowID)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
if (Window != NULL)
SelectedWindow = Window;
}
/******************************************************************************
* Returns the window drawn at the given position, NULL if none. *
******************************************************************************/
_IntrWindowStruct *_IntrWndwGetWndwInPos(int x, int y)
{
int Xmin, Ymin, Xmax, Ymax, FrameWidth, HeaderHeight;
_IntrWindowStruct *WndwList,
*RetWindow = NULL;
/* Find the last window covering the given coordinates. */
for (WndwList = GlblWindowsList;
WndwList != NULL;
WndwList = WndwList->Pnext) {
if (!WndwList -> MappedToScreen) continue;
Xmin = WndwList -> BBox.Xmin;
Ymin = WndwList -> BBox.Ymin;
Xmax = WndwList -> BBox.Xmax;
Ymax = WndwList -> BBox.Ymax;
FrameWidth = WndwList -> FrameWidth;
HeaderHeight = IntrWndwGetHeaderHeight("M", FrameWidth);
if (WndwList -> PDMenu != NULL) Ymin -= HeaderHeight;
if (WndwList -> DrawHeader && WndwList -> Name != NULL)
Ymin -= HeaderHeight;
switch (WndwList -> VScrlBar) {
case INTR_SCRLBAR_LEFT:
Xmin -= _INTR_SCROLL_BAR_WIDTH;
break;
case INTR_SCRLBAR_RIGHT:
Xmax += _INTR_SCROLL_BAR_WIDTH;
break;
}
switch (WndwList -> HScrlBar) {
case INTR_SCRLBAR_TOP:
Ymin -= _INTR_SCROLL_BAR_WIDTH;
break;
case INTR_SCRLBAR_BOTTOM:
Ymax += _INTR_SCROLL_BAR_WIDTH;
break;
}
if (Xmin - FrameWidth <= x && Xmax + FrameWidth >= x &&
Ymin - FrameWidth <= y && Ymax + FrameWidth >= y)
RetWindow = WndwList;
}
return RetWindow;
}
/******************************************************************************
* Test if given event should be handled internally. *
* The following events should be handled internally: *
* 1. SELECT event on a visible scroll bar. *
* Action: RedrawWindow after updating global AsyncEvent data. *
* 2. SELECT event on a visible pull down menu. *
* Action: Activate pull down menu relative ActionFunc. *
* Return TRUE if Internal event had occured. *
******************************************************************************/
IntrBType _IntrIsInternalEvent(IntrEventType Event, int x, int y)
{
static _IntrWindowStruct *LastWindow;
static IntrPullDownMenuStruct
*LastPDMenu = NULL;
static int
LastIndex = -1,
ActionFuncActive = FALSE;
int Xmin, Ymin, Xmax, Ymax, FrameWidth, HeaderHeight, Index;
IntrPullDownMenuStruct *PDMenu;
_IntrWindowStruct *Window;
/* Do not allow any internal events while something is poped up. */
if (!_IntrAllowInternalEvent()) return FALSE;
if ((Window = _IntrWndwGetWndwInPos(x, y)) != NULL) {
Xmin = Window -> BBox.Xmin;
Ymin = Window -> BBox.Ymin;
Xmax = Window -> BBox.Xmax;
Ymax = Window -> BBox.Ymax;
FrameWidth = Window -> FrameWidth;
HeaderHeight = IntrWndwGetHeaderHeight("M", FrameWidth);
_IntrAsyncLastEvent.Window = Window;
_IntrAsyncLastEvent.X = x;
_IntrAsyncLastEvent.Y = y;
_IntrAsyncLastEvent.IntrEvent = Event;
_IntrAsyncLastEvent.AsyncEvent = ASYNC_EVNT_NONE;
if (Event == INTR_EVNT_SELECT) {
switch (Window -> HScrlBar) {
case INTR_SCRLBAR_TOP:
if (x <= Xmax && x >= Xmin &&
y < Ymin && y >= Ymin - _INTR_SCROLL_BAR_WIDTH - 1) {
_IntrAsyncLastEvent.R = ((IntrRType) (x - Xmin)) /
(Xmax - Xmin);
_IntrAsyncLastEvent.AsyncEvent = ASYNC_EVNT_HSCRLBAR;
}
Ymin -= _INTR_SCROLL_BAR_WIDTH + 1; /* For VScrlBar. */
break;
case INTR_SCRLBAR_BOTTOM:
if (x <= Xmax && x >= Xmin &&
y > Ymax && y <= Ymax + _INTR_SCROLL_BAR_WIDTH + 1) {
_IntrAsyncLastEvent.R = ((IntrRType) (x - Xmin)) /
(Xmax - Xmin);
_IntrAsyncLastEvent.AsyncEvent = ASYNC_EVNT_HSCRLBAR;
}
Ymax += _INTR_SCROLL_BAR_WIDTH + 1; /* For VScrlBar. */
break;
}
switch (Window -> VScrlBar) {
case INTR_SCRLBAR_LEFT:
if (x < Xmin && x >= Xmin - _INTR_SCROLL_BAR_WIDTH - 1 &&
y <= Ymax && y >= Ymin) {
_IntrAsyncLastEvent.R = ((IntrRType) (y - Ymin)) /
(Ymax - Ymin);
_IntrAsyncLastEvent.AsyncEvent = ASYNC_EVNT_VSCRLBAR;
}
break;
case INTR_SCRLBAR_RIGHT:
if (x > Xmax && x <= Xmax + _INTR_SCROLL_BAR_WIDTH + 1 &&
y <= Ymax && y >= Ymin) {
_IntrAsyncLastEvent.R = ((IntrRType) (y - Ymin)) /
(Ymax - Ymin);
_IntrAsyncLastEvent.AsyncEvent = ASYNC_EVNT_VSCRLBAR;
}
break;
}
if (_IntrAsyncLastEvent.AsyncEvent != ASYNC_EVNT_NONE) {
/* Move window to top (last) of list. */
DeleteWindowFromGlblList(Window);
InsertWindowLastGlblList(Window);
RedrawWindow(Window);
_IntrAsyncLastEvent.AsyncEvent = ASYNC_EVNT_NONE;
return TRUE;
}
}
if (Window -> HScrlBar == INTR_SCRLBAR_TOP)
Ymin -= _INTR_SCROLL_BAR_WIDTH;
Xmin -= FrameWidth;
Xmax += FrameWidth;
if (!ActionFuncActive && (PDMenu = Window -> PDMenu) != NULL) {
if (x > Xmin && x < Xmax &&
y > Ymin - HeaderHeight - FrameWidth &&
y < Ymin - FrameWidth &&
(Index = (x - Xmin) / PDMenu -> DrawnEntryWidth) <
PDMenu -> NumOfEntries) {
switch (Event) {
case INTR_EVNT_SELECT:
_IntrAsyncLastEvent.PDBottom = Ymin - FrameWidth;
_IntrAsyncLastEvent.PDLeft = Xmin +
PDMenu -> DrawnEntryWidth * Index;
_IntrAsyncLastEvent.AsyncEvent = ASYNC_EVNT_PDMENU;
ActionFuncActive = TRUE;
PDMenu -> _ActiveIndex = Index;
delay(250); /* Make sure no events... */
IntrInputFlush();
(PDMenu -> ActionFuncs[Index])(Index);
PDMenu -> _ActiveIndex = -1;
ActionFuncActive = FALSE;
break;
default:
if (PDMenu != LastPDMenu || Index != LastIndex) {
if (LastPDMenu != NULL)
_IntrPullDownInvertEntry(LastIndex, LastWindow);
_IntrPullDownInvertEntry(Index, Window);
LastPDMenu = PDMenu;
LastWindow = Window;
LastIndex = Index;
}
break;
}
return TRUE;
}
}
}
if (!ActionFuncActive && LastPDMenu != NULL) {
_IntrPullDownInvertEntry(LastIndex, LastWindow);
LastPDMenu = NULL;
}
return FALSE;
}
/******************************************************************************
* Delete a window from global window list. *
******************************************************************************/
static void DeleteWindowFromGlblList(_IntrWindowStruct *Window)
{
_IntrWindowStruct
*WindowTail = GlblWindowsList;
if (WindowTail == NULL)
FATAL_ERROR("Window to delete not found.\n");
if (WindowTail == Window) {
/* Its top window - make global list point on second window. */
GlblWindowsList = GlblWindowsList -> Pnext;
}
else {
/* Scan the list until the window is found. */
while (WindowTail -> Pnext != NULL) {
if (WindowTail -> Pnext == Window) break;
WindowTail = WindowTail -> Pnext;
}
if (WindowTail -> Pnext == NULL)
FATAL_ERROR("Window to delete not found.\n");
WindowTail -> Pnext = WindowTail -> Pnext -> Pnext;
}
Window -> Pnext = NULL;
}
/******************************************************************************
* Insert a window to global window list as first. *
* This may usually happen as a result of a window push operation. *
******************************************************************************/
static void InsertWindowFirstGlblList(_IntrWindowStruct *Window)
{
if (GlblWindowsList != NULL &&
GlblWindowsList -> WindowType & INTR_WNDW_ROOT) {
/* Root window should always be left at the bottom (first). */
Window -> Pnext = GlblWindowsList -> Pnext;
GlblWindowsList -> Pnext = Window;
}
else {
Window -> Pnext = GlblWindowsList;
GlblWindowsList = Window;
}
}
/******************************************************************************
* Insert a window to global window list as last. *
* This may usually happen as a result of a window pop operation. *
******************************************************************************/
static void InsertWindowLastGlblList(_IntrWindowStruct *Window)
{
_IntrWindowStruct
*WindowTail = GlblWindowsList;
if (WindowTail == NULL)
GlblWindowsList = Window;
else {
while(WindowTail -> Pnext != NULL) WindowTail = WindowTail -> Pnext;
WindowTail -> Pnext = Window;
}
}
/******************************************************************************
* Routine to create a new window. Note this routine does not map it onto the *
* screen (i.e. make it visible) but only defines another window. *
******************************************************************************/
int IntrWndwCreate(char *WindowName,
int FrameWidth,
IntrBBoxStruct *BBox,
IntrColorType FrameColor,
IntrColorType BackColor,
IntrCursorShapeStruct *Cursor,
IntrPullDownMenuStruct *PDMenu,
IntrIntFunc RefreshFunc)
{
_IntrWindowStruct
*Window = _IntrMalloc(sizeof(_IntrWindowStruct));
Window -> WindowID = WindowIDCounter++;
Window -> WindowType = INTR_WNDW_GRAPH;
Window -> Name = WindowName;
Window -> DrawHeader = TRUE;
Window -> WindowFullSize = FALSE;
Window -> StatusLeft = Window -> StatusRight = NULL;
Window -> MappedToScreen = FALSE;
Window -> FrameWidth = FrameWidth;
BBox -> _Dx = BBox -> Xmax - BBox -> Xmin;
BBox -> _Dy = BBox -> Ymax - BBox -> Ymin;
GEN_COPY(&Window -> BBox, BBox, sizeof(IntrBBoxStruct));
Window -> FrameColor = FrameColor;
Window -> BackColor = BackColor;
Window -> HScrlBarColor = Window -> VScrlBarColor = INTR_COLOR_RED;
Window -> HScrlBar = Window -> VScrlBar = INTR_SCRLBAR_NONE;
GEN_COPY(&Window -> Cursor, Cursor, sizeof(IntrCursorShapeStruct));
Window -> FBBox.FXmin = DEFAULT_FXMIN;
Window -> FBBox.FYmin = DEFAULT_FYMIN;
Window -> FBBox.FXmax = DEFAULT_FXMAX;
Window -> FBBox.FYmax = DEFAULT_FYMAX;
Window -> FBBox._FDx = Window -> FBBox.FXmax - Window -> FBBox.FXmin;
Window -> FBBox._FDy = Window -> FBBox.FYmax - Window -> FBBox.FYmin;
Window -> PDMenu = PDMenu;
Window -> RefreshFunc = RefreshFunc;
Window -> TextInfo = NULL;
Window -> Pnext = NULL;
Window -> ZoomFactor = 0;
Window -> PanFactorX = Window -> PanFactorY = 0;
if (PDMenu != NULL)
PDMenu -> WindowID = Window -> WindowID;
InsertWindowLastGlblList(Window);
return Window -> WindowID;
}
/******************************************************************************
* Routine to set a window to be a root (back ground) window. *
******************************************************************************/
void IntrWndwSetRoot(int RootWindowID)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(RootWindowID);
IntrWndwPop(RootWindowID, TRUE, FALSE);
Window -> WindowType |= INTR_WNDW_ROOT;
}
/******************************************************************************
* Routine to map window to screen if not already mapped and place it above *
* all other windows. *
******************************************************************************/
void IntrWndwPop(int WindowID, IntrBType DoRedraw, IntrBType DoClear)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
if (Window -> WindowType & INTR_WNDW_ROOT) return; /* Dont pop root. */
Window -> MappedToScreen = TRUE;
DrawingWindow = Window;
GRSetZoomFactor(DrawingWindow -> ZoomFactor);
GRSetPanFactors(DrawingWindow -> PanFactorX, DrawingWindow -> PanFactorY);
GRSetViewPort(DrawingWindow -> BBox.Xmin,
DrawingWindow -> BBox.Ymin,
DrawingWindow -> BBox.Xmax,
DrawingWindow -> BBox.Ymax);
if (!IntrWndwIsAllVisible(WindowID)) {
if (DoRedraw)
RedrawWindow(Window);
else if (DoClear)
MoveWindowToTop(Window);
}
else {
/* Window is definitelly visible - only redraw if required. */
if (DoRedraw)
RedrawWindow(Window);
}
DeleteWindowFromGlblList(Window); /* Move window to top (last) of list. */
InsertWindowLastGlblList(Window);
}
/******************************************************************************
* Boolean function to determine if two given bbox domains overlap. *
******************************************************************************/
static IntrBType WindowBBoxOverlap(IntrBBoxStruct *BBox1,
IntrBBoxStruct *BBox2)
{
return !(BBox1 -> Xmax < BBox2 -> Xmin ||
BBox1 -> Ymax < BBox2 -> Ymin ||
BBox2 -> Xmax < BBox1 -> Xmin ||
BBox2 -> Ymax < BBox1 -> Ymin);
}
/******************************************************************************
* Routine to map window to screen if not already mapped and place it below *
* all other windows. *
******************************************************************************/
void IntrWndwPush(int WindowID, IntrBType DoRedraw)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
if (Window -> WindowType & INTR_WNDW_ROOT) return; /* Dont push root. */
if (!Window -> MappedToScreen) Window -> MappedToScreen = TRUE;
DeleteWindowFromGlblList(Window); /* Move wndw to list bottom (first). */
InsertWindowFirstGlblList(Window);
if (DoRedraw)
IntrWndwRedrawAll(); /* Update all windows. */
}
/******************************************************************************
* Routine to map window to screen if not already mapped and place it below *
* all other windows. *
******************************************************************************/
IntrBType IntrWndwIsAllVisible(int WindowID)
{
_IntrWindowStruct *W,
*Window = _IntrFindWndwUsingID(WindowID);
if (!Window -> MappedToScreen) return FALSE;
for (W = Window -> Pnext; W != NULL; W = W -> Pnext)
if (WindowBBoxOverlap(&Window -> BBox, &W -> BBox)) return FALSE;
return TRUE;
}
/******************************************************************************
* Routine to set a bound on window move/resize operations. *
******************************************************************************/
void IntrWndwSetResizeBBox(IntrBBoxStruct *BBox)
{
GEN_COPY(&ResizeBBox, BBox, sizeof(IntrBBoxStruct));
ResizeBBox._Dx = ResizeBBox.Xmax - ResizeBBox.Xmin;
ResizeBBox._Dy = ResizeBBox.Ymax - ResizeBBox.Ymin;
}
/******************************************************************************
* Select a window by picking a point on it. *
******************************************************************************/
int IntrWndwPick(void)
{
int x, y;
_IntrWindowStruct *Window;
IntrCursorShapeStruct Cursor;
IntrEventType Event;
Cursor.CursorType = INTR_CURSOR_ARROW;
IntrDrawMessage("Select window", INTR_COLOR_YELLOW, INTR_COLOR_YELLOW);
IntrPushCursorType();
IntrSetCursorType(&Cursor);
do {
Event = IntrGetEventWait(&x, &y);
ClipPositionToResizeBBox(&x, &y, 0, 0);
}
while (Event != INTR_EVNT_SELECT && Event != INTR_EVNT_ABORT);
IntrPopCursorType();
IntrEraseMessage();
if (Event == INTR_EVNT_ABORT) return FALSE;
Window = _IntrWndwGetWndwInPos(x, y);
if (Window != NULL)
return Window -> WindowID;
else
return -1;
}
/******************************************************************************
* Clip given coordinates to resize bounding box and update GRCurrentCursorX/Y *
* if necessary. *
******************************************************************************/
static void ClipPositionToResizeBBox(int *x, int *y, int Width, int Height)
{
if (ResizeBBox.Xmin > *x - Width)
GRCurrentCursorX = *x = ResizeBBox.Xmin + Width;
if (ResizeBBox.Xmax < *x + Width)
GRCurrentCursorX = *x = ResizeBBox.Xmax - Width;
if (ResizeBBox.Ymin > *y - Height)
GRCurrentCursorY = *y = ResizeBBox.Ymin + Height;
if (ResizeBBox.Ymax < *y + Height)
GRCurrentCursorY = *y = ResizeBBox.Ymax - Height;
}
/******************************************************************************
* Routine to resize a window. Returns TRUE if window has been modified. *
******************************************************************************/
IntrBType IntrWndwResize(int WindowID, IntrBType Refresh)
{
int x, y;
char Str[80];
IntrEventType Event;
IntrCursorShapeStruct Cursor;
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
IntrBBoxStruct
*BBox = &Window -> BBox;
int Xmin = BBox -> Xmin,
Ymin = BBox -> Ymin,
Xmax = BBox -> Xmax,
Ymax = BBox -> Ymax;
if (Refresh) MoveWindowToTop(Window);
/* Pick the corner of the window to move. */
if (Window -> Name != NULL) {
sprintf(Str, "Select first \"%s\" corner", Window -> Name);
IntrDrawMessage(Str, INTR_COLOR_YELLOW, INTR_COLOR_YELLOW);
}
else
IntrDrawMessage("Select first window corner", INTR_COLOR_YELLOW,
INTR_COLOR_YELLOW);
Cursor.CursorType = INTR_CURSOR_ARROW;
IntrPushCursorType();
IntrSetCursorType(&Cursor);
GRCurrentCursorX = (Xmin + Xmax) >> 1;
GRCurrentCursorY = (Ymin + Ymax) >> 1;
do {
Event = IntrGetEventWait(&x, &y);
ClipPositionToResizeBBox(&x, &y, 0, 0);
}
while (Event != INTR_EVNT_SELECT && Event != INTR_EVNT_ABORT);
IntrEraseMessage();
IntrPopCursorType();
if (Event == INTR_EVNT_ABORT) {
if (Refresh) IntrWndwRedrawAll();
return FALSE;
}
IntrDrawMessage("Select second corner position", INTR_COLOR_YELLOW,
INTR_COLOR_YELLOW);
BBox -> Xmin = Cursor.LastX = GRCurrentCursorX = x;
BBox -> Ymin = Cursor.LastY = GRCurrentCursorY = y;
IntrPushCursorType();
Cursor.CursorType = INTR_CURSOR_BOX_LAST;
Cursor.LastHV = TRUE;
IntrSetCursorType(&Cursor);
do {
Event = IntrGetEventWait(&x, &y);
ClipPositionToResizeBBox(&x, &y, 0, 0);
}
while (Event != INTR_EVNT_SELECT && Event != INTR_EVNT_ABORT);
IntrPopCursorType();
IntrEraseMessage();
if (Event == INTR_EVNT_ABORT) {
if (Refresh) IntrWndwRedrawAll();
return FALSE;
}
BBox -> Xmax = x;
BBox -> Ymax = y;
if (BBox -> Xmax < BBox -> Xmin)
SWAP(BBox -> Xmax, BBox -> Xmin, int);
if (BBox -> Ymax < BBox -> Ymin)
SWAP(BBox -> Ymax, BBox -> Ymin, int);
/* Make sure window is not too small. */
if (BBox -> Xmax - BBox -> Xmin < MIN_WINDOW_SIZE)
BBox -> Xmax = BBox -> Xmin + MIN_WINDOW_SIZE;
if (BBox -> Ymax - BBox -> Ymin < MIN_WINDOW_SIZE)
BBox -> Ymax = BBox -> Ymin + MIN_WINDOW_SIZE;
BBox -> _Dx = BBox -> Xmax - BBox -> Xmin;
BBox -> _Dy = BBox -> Ymax - BBox -> Ymin;
if (Refresh) IntrWndwRedrawAll();
return TRUE;
}
/******************************************************************************
* Routine to zoom/unzoom a window to/from full size from/to current size. *
* It is assumed the full size specification is saved in ResizeBBox. *
******************************************************************************/
void IntrWndwFullSize(int WindowID, IntrBType Refresh)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
IntrBBoxStruct
*BBox = &Window -> BBox;
if (Window -> WindowFullSize) {
GEN_COPY(&Window -> BBox, &Window -> PushBBox, sizeof(IntrBBoxStruct));
Window -> WindowFullSize = FALSE;
if (Refresh) IntrWndwRedrawAll();
}
else {
GEN_COPY(&Window -> PushBBox, &Window -> BBox, sizeof(IntrBBoxStruct));
GEN_COPY(BBox, &ResizeBBox, sizeof(IntrBBoxStruct));
Window -> WindowFullSize = TRUE;
if (Refresh) RedrawWindow(Window);
}
}
/******************************************************************************
* Routine to move a window. Returns TRUE if window has been modified. *
******************************************************************************/
IntrBType IntrWndwMove(int WindowID, IntrBType Refresh)
{
int x, y;
IntrEventType Event;
IntrCursorShapeStruct Cursor;
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
IntrBBoxStruct
*BBox = &Window -> BBox;
int Xmin = BBox -> Xmin,
Ymin = BBox -> Ymin,
Xmax = BBox -> Xmax,
Ymax = BBox -> Ymax;
if (Refresh) MoveWindowToTop(Window);
/* Pick the new position of the window. */
IntrPushCursorType();
Cursor.CursorType = INTR_CURSOR_BOX;
Cursor.Width = (Xmax - Xmin) >> 1;
Cursor.Height = (Ymax - Ymin) >> 1;
IntrSetCursorType(&Cursor);
GRCurrentCursorX = (Xmin + Xmax) >> 1;
GRCurrentCursorY = (Ymin + Ymax) >> 1;
IntrDrawMessage("Select new window position", INTR_COLOR_YELLOW,
INTR_COLOR_YELLOW);
do {
Event = IntrGetEventWait(&x, &y);
ClipPositionToResizeBBox(&x, &y, Cursor.Width, Cursor.Height);
}
while (Event != INTR_EVNT_SELECT && Event != INTR_EVNT_ABORT);
IntrEraseMessage();
IntrPopCursorType();
if (Event == INTR_EVNT_SELECT) {
BBox -> Xmin = x - Cursor.Width;
BBox -> Ymin = y - Cursor.Height;
BBox -> Xmax = BBox -> Xmin + BBox -> _Dx;
BBox -> Ymax = BBox -> Ymin + BBox -> _Dy;
if (Refresh) IntrWndwRedrawAll();
return TRUE;
}
else {
if (Refresh) IntrWndwRedrawAll();
return FALSE;
}
}
/******************************************************************************
* Routine to hide a window - unmap it from screen. *
* If Refresh then screen is updated on this hidden window. *
******************************************************************************/
void IntrWndwHide(int WindowID, IntrBType Refresh)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
if (Window -> MappedToScreen) {
Window -> MappedToScreen = FALSE;
if (Refresh) IntrWndwRedrawAll();
}
}
/******************************************************************************
* Routine to delete a window. *
* If Refresh then screen is updated on this hidden window. *
******************************************************************************/
void IntrWndwDelete(int WindowID, IntrBType Refresh)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
IntrWndwHide(WindowID, Refresh);
DeleteWindowFromGlblList(Window);
if (Window -> TextInfo != NULL)
_IntrTextWndwDelete(Window -> TextInfo);
if (Window -> PDMenu != NULL)
IntrPullDownMenuDelete(Window -> PDMenu);
_IntrFree(Window);
}
/******************************************************************************
* Routine to return window bounding box. *
******************************************************************************/
IntrBBoxStruct *IntrWndwGetBBox(int WindowID)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
return &Window -> BBox;
}
/******************************************************************************
* Routine to return window float bounding box. *
******************************************************************************/
IntrFBBoxStruct *IntrWndwGetFBBox(int WindowID)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
return &Window -> FBBox;
}
/******************************************************************************
* Routine to return window border color. *
******************************************************************************/
IntrColorType IntrWndwGetFrameColor(int WindowID)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
return Window -> FrameColor;
}
/******************************************************************************
* Routine to return window back ground color. *
******************************************************************************/
IntrColorType IntrWndwGetBackGroundColor(int WindowID)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
return Window -> BackColor;
}
/******************************************************************************
* Routine to return window cursor shape. *
******************************************************************************/
IntrCursorShapeStruct *IntrWndwGetCursorShape(int WindowID)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
return &Window -> Cursor;
}
/******************************************************************************
* Routine to return the pull down menu of the window (if any). *
******************************************************************************/
IntrPullDownMenuStruct *IntrWndwGetPullDownMenu(int WindowID)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
return Window -> PDMenu;
}
/******************************************************************************
* Routine to return the zoom factor drawing of the window. *
******************************************************************************/
int IntrWndwGetZoomFactor(int WindowID)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
return Window -> ZoomFactor;
}
/******************************************************************************
* Routine to get window refresh function. *
******************************************************************************/
IntrIntFunc IntrWndwGetRefreshFunc(int WindowID)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
return Window -> RefreshFunc;
}
/******************************************************************************
* Routine to return the panning values for drawing in the window. *
******************************************************************************/
void IntrWndwGetPanFactors(int WindowID, int *x, int *y)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
*x = Window -> PanFactorX;
*y = Window -> PanFactorY;
}
/******************************************************************************
* Routine to set window Name. *
******************************************************************************/
void IntrWndwSetName(int WindowID, char *Name)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
Window -> Name = Name;
}
/******************************************************************************
* Routine to set the display of a window header (also requires Name slot) *
******************************************************************************/
void IntrWndwSetDrawHeader(int WindowID, IntrBType DrawHeader)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
Window -> DrawHeader = DrawHeader;
}
/******************************************************************************
* Routine to set window BBox - practically resize/move the window. *
******************************************************************************/
void IntrWndwSetBBox(int WindowID, IntrBBoxStruct *BBox)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
BBox -> _Dx = BBox -> Xmax - BBox -> Xmin;
BBox -> _Dy = BBox -> Ymax - BBox -> Ymin;
GEN_COPY(&Window -> BBox, BBox, sizeof(IntrBBoxStruct));
}
/******************************************************************************
* Routine to set window FBBox - practically translate/scale floating drawing. *
******************************************************************************/
void IntrWndwSetFBBox(int WindowID, IntrFBBoxStruct *FBBox)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
FBBox -> _FDx = FBBox -> FXmax - FBBox -> FXmin;
FBBox -> _FDy = FBBox -> FYmax - FBBox -> FYmin;
GEN_COPY(&Window -> FBBox, FBBox, sizeof(IntrFBBoxStruct));
}
/******************************************************************************
* Routine to set window border color. *
******************************************************************************/
void IntrWndwSetFrameColor(int WindowID, IntrColorType FrameColor)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
Window -> FrameColor = FrameColor;
}
/******************************************************************************
* Routine to set window back ground color. *
******************************************************************************/
void IntrWndwSetBackGroundColor(int WindowID, IntrColorType BackColor)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
Window -> BackColor = BackColor;
}
/******************************************************************************
* Routine to set window scroll bar. *
******************************************************************************/
void IntrWndwSetScrlBar(int WindowID,
IntrBType IsVertical,
IntrScrlBarType ScrlBar,
IntrColorType ScrlBarColor)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
if (IsVertical) {
Window -> VScrlBar = ScrlBar;
Window -> VScrlBarColor = ScrlBarColor;
}
else {
Window -> HScrlBar = ScrlBar;
Window -> HScrlBarColor = ScrlBarColor;
}
}
/******************************************************************************
* Routine to set window cursor shape. *
******************************************************************************/
void IntrWndwSetCursorShape(int WindowID, IntrCursorShapeStruct *Cursor)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
GEN_COPY(&Window -> Cursor, Cursor, sizeof(IntrCursorShapeStruct));
}
/******************************************************************************
* Routine to set window pull down menu. *
******************************************************************************/
void IntrWndwSetPullDownMenu(int WindowID, IntrPullDownMenuStruct *PDMenu)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
if (Window -> PDMenu)
IntrPullDownMenuDelete(Window -> PDMenu);
Window -> PDMenu = PDMenu;
}
/******************************************************************************
* Routine to set window refresh function. *
******************************************************************************/
void IntrWndwSetRefreshFunc(int WindowID, IntrIntFunc RefreshFunc)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
Window -> RefreshFunc = RefreshFunc;
}
/******************************************************************************
* Routine to update panning values of drawings in window. *
******************************************************************************/
void IntrWndwUpdatePanning(int WindowID, int x, int y)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
Window -> PanFactorX += x;
Window -> PanFactorY += y;
}
/******************************************************************************
* Routine to set panning values of drawings in window. *
******************************************************************************/
void IntrWndwSetPanning(int WindowID, int x, int y)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
Window -> PanFactorX = x;
Window -> PanFactorY = y;
}
/******************************************************************************
* Routine to update zoom value of drawings in window. *
******************************************************************************/
void IntrWndwUpdateZoom(int WindowID, int Zoom)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
Window -> ZoomFactor += Zoom;
}
/******************************************************************************
* Routine to update zoom value of drawings in window. *
******************************************************************************/
void IntrWndwSetZoom(int WindowID, int Zoom)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
Window -> ZoomFactor = Zoom;
}
/******************************************************************************
* Routine to set status string on left and right of window header. *
******************************************************************************/
void IntrWndwSetStatus(int WindowID, char *StatusLeft, char *StatusRight,
IntrBType Refresh)
{
_IntrWindowStruct
*Window = _IntrFindWndwUsingID(WindowID);
if (Refresh && Window -> Name && Window -> MappedToScreen) {
/* If this window is not the top one - pop it up. */
if (Window -> Pnext != NULL)
IntrWndwPop(WindowID, TRUE, FALSE);
IntrWndwPutStatus(Window,
IntrAllocColor(Window -> BackColor,
INTR_INTENSITY_HIGH));
}
if (Window -> StatusLeft)
_IntrFree(Window -> StatusLeft);
if (Window -> StatusRight)
_IntrFree(Window -> StatusRight);
Window -> StatusLeft = strdup(StatusLeft);
Window -> StatusRight = strdup(StatusRight);
if (Refresh && Window -> Name && Window -> MappedToScreen)
IntrWndwPutStatus(Window,
IntrAllocColor(Window -> FrameColor,
INTR_INTENSITY_VHIGH));
}
/******************************************************************************
* Line in window space. *
******************************************************************************/
void IntrWndwILine(int x1, int y1, int x2, int y2)
{
GRSLine(x1, y1, x2, y2);
}
/******************************************************************************
* Line in object space. *
******************************************************************************/
void IntrWndwRLine(IntrRType x1, IntrRType y1, IntrRType x2, IntrRType y2)
{
IntrWndwRMoveTo(x1, y1);
IntrWndwRLineTo(x2, y2);
}
/******************************************************************************
* MoveTo in window space. *
******************************************************************************/
void IntrWndwIMoveTo(int x, int y)
{
GRSMoveTo(x, y);
}
/******************************************************************************
* MoveTo in object space. *
******************************************************************************/
void IntrWndwRMoveTo(IntrRType x, IntrRType y)
{
GRSMoveTo(MAP_OBJ_TO_WNDW_X(RealCursorX = x),
MAP_OBJ_TO_WNDW_Y(RealCursorY = y));
}
/******************************************************************************
* LineTo in window space. *
******************************************************************************/
void IntrWndwILineTo(int x, int y)
{
GRSLineTo(x, y);
}
/******************************************************************************
* LineTo in object space. *
******************************************************************************/
void IntrWndwRLineTo(IntrRType x, IntrRType y)
{
GRSLineTo(MAP_OBJ_TO_WNDW_X(RealCursorX = x),
MAP_OBJ_TO_WNDW_Y(RealCursorY = y));
}
/******************************************************************************
* MoveRel in window space. *
******************************************************************************/
void IntrWndwIMoveRel(int x, int y)
{
GRSMoveRel(x, y);
}
/******************************************************************************
* MoveRel in object space (not sure what it actually means). *
******************************************************************************/
void IntrWndwRMoveRel(IntrRType x, IntrRType y)
{
GRSMoveRel(MAP_OBJ_TO_WNDW_X(x) - MAP_OBJ_TO_WNDW_X(RealCursorX),
MAP_OBJ_TO_WNDW_Y(y) - MAP_OBJ_TO_WNDW_X(RealCursorY));
RealCursorX = x;
RealCursorY = y;
}
/******************************************************************************
* LineRel in window space. *
******************************************************************************/
void IntrWndwILineRel(int x, int y)
{
GRSLineRel(x, y);
}
/******************************************************************************
* LineRel in object space (not sure what it actually means). *
******************************************************************************/
void IntrWndwRLineRel(IntrRType x, IntrRType y)
{
GRSLineRel(MAP_OBJ_TO_WNDW_X(x) - MAP_OBJ_TO_WNDW_X(RealCursorX),
MAP_OBJ_TO_WNDW_Y(y) - MAP_OBJ_TO_WNDW_X(RealCursorY));
RealCursorX = x;
RealCursorY = y;
}
/******************************************************************************
* Poly in window space. *
******************************************************************************/
void IntrWndwIPoly(int n, int *Points, int Fill)
{
GRPoly(n, Points, Fill);
}
/******************************************************************************
* Bar in window space. *
******************************************************************************/
void IntrWndwIBar(int x1, int y1, int x2, int y2)
{
GRBar(x1, y1, x2, y2);
}
/******************************************************************************
* Bar in object space. *
******************************************************************************/
void IntrWndwRBar(IntrRType x1,
IntrRType y1,
IntrRType x2,
IntrRType y2)
{
GRBar(MAP_OBJ_TO_WNDW_X(x1), MAP_OBJ_TO_WNDW_Y(y1),
MAP_OBJ_TO_WNDW_X(x2), MAP_OBJ_TO_WNDW_Y(y2));
}
/******************************************************************************
* Circle in window space. *
******************************************************************************/
void IntrWndwICircle(int x, int y, int r)
{
GRCircle(x, y, r);
}
/******************************************************************************
* Circle in object space. *
******************************************************************************/
void IntrWndwRCircle(IntrRType x, IntrRType y, IntrRType r)
{
GRCircle(MAP_OBJ_TO_WNDW_X(x), MAP_OBJ_TO_WNDW_Y(y),
(int) (DrawingWindow -> BBox._Dx * r));
}
/******************************************************************************
* Arc in window space. *
******************************************************************************/
void IntrWndwIArc(int x, int y, int StAngle, int EndAngle, int r)
{
GRArc(x, y, StAngle, EndAngle, r);
}
/******************************************************************************
* Arc in object space. *
******************************************************************************/
void IntrWndwRArc(IntrRType x,
IntrRType y,
int StAngle,
int EndAngle,
IntrRType r)
{
GRArc(MAP_OBJ_TO_WNDW_X(x), MAP_OBJ_TO_WNDW_Y(y), StAngle, EndAngle,
(int) (DrawingWindow -> BBox._Dx * r));
}
/******************************************************************************
* Text in window space. *
******************************************************************************/
void IntrWndwIText(int x, int y, char *s)
{
GRText(x, y, s);
}
/******************************************************************************
* Text in object space. *
******************************************************************************/
void IntrWndwRText(IntrRType x, IntrRType y, char *s)
{
GRSText(MAP_OBJ_TO_WNDW_X(x), MAP_OBJ_TO_WNDW_Y(y), s);
}